<?php
/**
  * @file       Manager.inc 
  * @brief      提供常用的繁瑣指令簡單化
  * @author     Colin
  * @date       2013-01-13
 */
class Manager
{
    final public static function isLocalhost()
    {
        return '127.0.0.1' === self::server('SERVER_ADDR');
    }
    final public static function session_start()
    {
       ! isset($_SESSION) && ! headers_sent() && session_start();
    }
            
    /**
      * @brief IP相關函式組
     */
    final public static function isIP($ip)
    {
        $_ip = long2ip(ip2long($ip));
        return ! ('0.0.0.0'==$_ip);
    }
    
    final public static function ip(&$ip='')
    {
        $re = '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/';
        $ip = getenv("HTTP_CLIENT_IP");
        if (!$ip) {$ip = getenv("HTTP_X_FORWARDED_FOR");}
        if (!$ip) {$ip = getenv("REMOTE_ADDR");}
        if (!$ip && isset($_SERVER['REMOTE_ADDR'])) {$ip = $_SERVER['REMOTE_ADDR'];}
        if (!preg_match($re, $ip))
        {
            $ip = NULL;
            return false;
        }
        return $ip;
    }
    
    ///位元開關
    final public static function bitSwitch($int_option, $bit_location)//:Boolean
    {
        return (boolean)($int_option & $bit_location);
    }

    /// 特徵聲明 get_declared_traits()
    /// 介面聲明 get_declared_interfaces()
    /// 類別聲明 get_declared_classes()
    /// 函式定義 get_defined_functions()
    /// 檔案使用
    final public static function get_included_files()
    {
        $retval = array();
        foreach (get_included_files() as $file)
        {
            $retval[$file] = filesize($file). ' bytes';
        }
        return $retval;
    }
    
    /// 壓力測試
    final public static function stressTest(Closure $closure, $times=100)
    {
        self::stopwatch(1);
        for ($i=$times; $i>0; --$i)
        {
            $closure();
        }
        return "<br />執行{$times}次 ".self::stopwatch(0);
    }
    /// 系統計時器
    private static $stopwatch_microtime=0;
    final public static function stopwatch($bool=false)
    {
        if ($bool)
        {
            self::$stopwatch_microtime = microtime(1);
            return;
        }
        $t = (0 === self::$stopwatch_microtime)? 0 : microtime(1) - self::$stopwatch_microtime ;
        return '<div>花費時間:'.((($t*1000000)>>0)/1000) . ' ms</div>';
    }
    ///記憶體銷耗測試
    private static $memry_usage=0;
    final public static function memory($bool=false)
    {
        if ('peak' === $bool)
        {// ('peak' == 0) -> true ??為什麼
            return memory_get_peak_usage(1);
        }
        if ($bool && 'peak' !== $bool)
        {
            self::$memry_usage = memory_get_usage(1);
            return;
        }
        
        if ('peak' === $bool)
        {
            $size = memory_get_peak_usage(1);
        }
        else
        {
            $size = (memory_get_usage(1) - self::$memry_usage);
        }
        $unit=array('b','kb','mb','gb','tb','pb');
        $i = floor(log($size,1024));
        $pow = pow(1024, $i);
        if (0 == $pow) {$pow = 1;}//分數有可能為0
        return '<div>使用記憶體:'.round($size/$pow,2).' '.$unit[$i].'</div>';
    }
    
    private static $register_path = array();
    public static function register($path)
    {
        ($realpath = realpath($path)) 
        and ! in_array($realpath, self::$register_path) 
        and (self::$register_path[] = $realpath);
    }
    private static $is_init = false;
    public static function init()
    {
        if ( ! self::$is_init)
        {
            self::$is_init = true;
            $reqister_path = &self::$register_path;
            spl_autoload_register(function($classname) use(&$reqister_path){
                $sub_filename = str_replace('\\', '/', $classname) .'.php';
                array_map(function($base) use($sub_filename) {
                    $filename = "{$base}/{$sub_filename}";
                    if (is_readable($filename))
                    {
                        return ! require_once $filename;
                    }
                }, $reqister_path);
            });
        }
    }
}
Manager::init();
Manager::register(__DIR__.'/php');